# Abstract class for provider-specific ForecastGen implementations
import logging

class Forecast:
    """Struct-like class to clearly define the forecast format."""
    date_forecasted = None  # datetime.date indicating the day for which the 
                            # forecast is made in local time
    date_observed = None    # datetime.date indicating the day on which the 
                            # forecast is made in local time
    t_min = -274       # min temperature in Celsius
    t_max = -274       # max temperature in Celsius        

    def __init__(self, date_observed, date_forecasted, t_min, t_max):
        self.date_observed = date_observed
        self.date_forecasted = date_forecasted
        self.t_min = t_min
        self.t_max = t_max

    def __str__(self):
        ret = """\
Forecast for: {self.date_forecasted}
Retrieved on: {self.date_observed}
Min T: {self.t_min}
Max T: {self.t_max}
""".format(self=self)
        return ret
        

class ForecastGen:
    shortname = "common"
    url = ""
    log = None # logging instance
    # forecasts is a dictionary of daysfromnow: Forecast
    forecasts = {}

    def __init__(self, latitude, longitude):
        self.log = logging.getLogger(self.shortname)
        url = self.generate_url(latitude, longitude)

    def getforecast(self, daysfromnow):
        """Returns the forecast data for n days from now, fetching it from the
        web if necessary"""
        if self.forecasts == {}:
            self.log.debug("Fetching new forecasts from the web.")
            self.forecasts = self.processdata(self.fetchdata())
        return self.forecasts[daysfromnow]

    def generate_url(self, latitude, longitude):
        """Generates a fresh URL to get forecast data about the given 
        location."""
        raise NotImplementedError("generate_url undefined")

    def fetchdata(self, url=None):
        """Fetches the data from the web. 

        Returns a format suitable for use in processdata().
        """
        raise NotImplementedError("fetchdata undefined")

    def processdata(self, data):
        raise NotImplementedError("processdata undefined")    

    def shutup(self):
        self.log.setLevel(logging.WARN)
